//package com.archgeek.spark.examples;
//
//
//import java.text.NumberFormat;
//
//import org.apache.hadoop.hive.ql.exec.Description;
//import org.apache.hadoop.hive.ql.exec.UDF;
//import org.apache.hadoop.io.DoubleWritable;
//import org.apache.hadoop.io.Text;
//
//
//@Description(name = "fql_rate", value = "_FUNC_(x,y,z) - returns excel rate 汇率"
//        + "  > SELECT _FUNC_(500,510,1) FROM src LIMIT 1;\n")
//public class Fql_Execl_Rate extends UDF {
//    /**
//     * 实际利率法
//     *
//     * @param a
//     *            现值
//     * @param b
//     *            年金
//     * @param c
//     *            期数
//     * @param cnt
//     *            运算次数
//     * @param ina
//     *            误差位数
//     * @return 利率
//     */
//    public DoubleWritable execl_rate(DoubleWritable a, DoubleWritable b, DoubleWritable c, int cnt, int ina) {
//
//        double rate = 1, x, jd = 0.1, side = 0.1, i = 1;
//        if (c.get() == 1) {
//            cnt = 20;
//        }
//        if(c.get()==0){
//            cnt = 9;
//        }
//        do {
//            x = a.get() / b.get() - (Math.pow(1 + rate, c.get()) - 1) / (Math.pow(rate + 1, c.get()) * rate);
//            if (x * side > 0) {
//                side = -side;
//                jd *= 10;
//            }
//            rate += side / jd;
//        } while (i++ < cnt && Math.abs(x) >= 1 / Math.pow(10, ina));
//        if (i > cnt) {
//            return new DoubleWritable(Double.NaN);
//        }
//
//        return new DoubleWritable(rate);
//    }
//
//    public  Text evaluate(String aa, String bb, int c) {
//        double a = Double.parseDouble(aa);
//        double b = Double.parseDouble(bb);
//        double rate = 1, x, jd = 0.1, side = 0.1, i = 1;
//        Text text = new Text();
//        int cnt = 120;
//        int ina = 14;
////		if (c.get() == 1) {
////			cnt = 20;
////		}
//        if (c == 1) {
//            double cc = (b - a) / a;
//            NumberFormat nf = NumberFormat.getInstance();
//            nf.setMinimumFractionDigits(17);
//            String dddd = nf.format(cc);
//            text.set(dddd);
//            return text;
//        }
//        if(c<=0){
//            text.set("0");
//            return text;
//        }
//        do {
//            x = a / b - (Math.pow(1 + rate, c) - 1) / (Math.pow(rate + 1, c) * rate);
//            if (x * side > 0) {
//                side = -side;
//                jd *= 10;
//            }
//            rate += side / jd;
//        } while (i++ < cnt && Math.abs(x) >= 1 / Math.pow(10, ina));
//        if (i > cnt) {
//            text.set(rate + "");
//            return text;
//        }
//        text.set(rate + "");
//        return text;
//    }
//    public  Text evaluate(Object a, Object b, Object c) throws FQLSparkHiveUdfException {
//
//        if (a!=null && !"".equalsIgnoreCase(a.toString())
//                && b!=null && !"".equalsIgnoreCase(b.toString())
//                && c!=null && !"".equalsIgnoreCase(c.toString())){
//            int cc = Integer.parseInt(c.toString());
//            return this.evaluate(a.toString(), b.toString(), cc);
//        }else{
//            throw new FQLSparkHiveUdfException("The input parameter is wrong: first :"+ a +"\t second :" + b + "\t three :" +c);
//        }
//    }
//    public  String evaluate(double a, double b, int c) {
//        double rate = 1, x, jd = 0.1, side = 0.1, i = 1;
//        Text text = new Text();
//        int cnt = 120;
//        int ina = 14;
////		if (c.get() == 1) {
////			cnt = 20;
////		}
//        if (c == 1) {
//            double bb = b;
//            double aa = a;
//            double cc = (bb - aa) / aa;
//            NumberFormat nf = NumberFormat.getInstance();
//            nf.setMinimumFractionDigits(17);
//            String dddd = nf.format(cc);
//            text.set(dddd);
//            return text.toString();
//        }
//        if(c<=0){
//            text.set("0");
//            return text.toString();
//        }
//        do {
//            x = a / b - (Math.pow(1 + rate, c) - 1) / (Math.pow(rate + 1, c) * rate);
//            if (x * side > 0) {
//                side = -side;
//                jd *= 10;
//            }
//            rate += side / jd;
//        } while (i++ < cnt && Math.abs(x) >= 1 / Math.pow(10, ina));
//        if (i > cnt) {
//            text.set(rate + "");
//            return text.toString();
//        }
//        text.set(rate + "");
//        return text.toString();
//    }
//
//    public  Text evaluate(int aa, int bb, int c) {
//        double rate = 1, x, jd = 0.1, side = 0.1, i = 1;
//        Text text = new Text();
//        double a = aa;
//        double b = bb;
//        int cnt = 120;
//        int ina = 14;
//        if (c == 1) {
//            double cc = (b - a) / a;
//            NumberFormat nf = NumberFormat.getInstance();
//            nf.setMinimumFractionDigits(17);
//            String dddd = nf.format(cc);
//            text.set(dddd);
//            return text;
//        }
//        if(c<=0){
//            text.set("0");
//            return text;
//        }
//        do {
//            x = a / b - (Math.pow(1 + rate, c) - 1) / (Math.pow(rate + 1, c) * rate);
//            if (x * side > 0) {
//                side = -side;
//                jd *= 10;
//            }
//            rate += side / jd;
//        } while (i++ < cnt && Math.abs(x) >= 1 / Math.pow(10, ina));
//        if (i > cnt) {
//            text.set(rate + "");
//            return text;
//        }
//        text.set(rate + "");
//        return text;
//    }
//    public static void main(String agrs[]) throws FQLSparkHiveUdfException {
//        Fql_Execl_Rate rate = new Fql_Execl_Rate();
//        int 现值 = 500;
//        double 年金 = 510d;
//        int 期数 = 1;
//        // 计算120次，比Excel 20次要精确，误差精确到小数点后10位
//        System.out.println(rate.evaluate(现值, 年金, 期数));
//    }
//
//}
